home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ELYVER10.ZIP / MIKXMAS.ZIP / docs / watirq.doc < prev   
Encoding:
Text File  |  1995-11-20  |  3.5 KB  |  108 lines

  1. ┌───────────────────────┐
  2. │WATIRQ - What the F*CK?│
  3. └───────────────────────┘
  4.                          
  5. Date last modified: May 10, 1995
  6.  
  7. Have you ever tried installing your own timer interrupt using a watcom flat 
  8. model program? And did it work? NO? Well this document explains why and what 
  9. to do about it.
  10.  
  11.  
  12. The problem
  13. ===========
  14.  
  15. In the flat memory model watcom generates code which assumes DS==SS.. it
  16. does this even for interrupt handler code that you might have written such
  17. as:
  18.  
  19.         void interrupt handler(void)
  20.         {
  21.             char foo[10];
  22.             
  23.             foo[8]='a';
  24.  
  25.             ...        
  26.         }      
  27.                        
  28. Now, being the optimizing compiler watcom is, it'll generate code to access
  29. foo[8] through the DS segment register, instead of SS where the array 'foo' 
  30. really resides. If DS would contain the same selector as SS, this wouldn't 
  31. be any problem! but guess what: during interrupts SS is _NOT_ DS. The result 
  32. of this glitch ranges from stack overflows to really nasty reboots..
  33.  
  34. Maybe I am wrong in saying this is a compiler bug.. it seems that if you run 
  35. the same program using pmodew instead of dos4g, everything works just fine, 
  36. even though DS still isn't SS in most cases during interrupts (I checked). 
  37. Maybe pmodew allocates a new descriptor for every interrupt and maps it to 
  38. the same memory as DS (Daredevil?).
  39.  
  40.  
  41. The cure
  42. ========
  43.  
  44. The easiest way to fix the DS!=SS problem is to let the compiler know DS
  45. isn't SS so it won't try to access the stack through the data descriptor. 
  46. This is done by using the /zu compiler option, for every module that contains 
  47. code which is called from the interrupt.
  48.  
  49. As with all cures, this one has some sideeffects too.. the compiler will 
  50. start to complain if you try to pass the address of a variable that's on the
  51. stack using a near ptr (the flat model default), for example:
  52.  
  53.  
  54.         void DoCalculation(int *p)
  55.         {
  56.             *p=(420/10);
  57.         }
  58.  
  59.  
  60.         void foo(void)
  61.         {
  62.             int retval;
  63.                                          
  64.             DoCalculation(&retval);  // <- this line will generate a warning
  65.         }
  66.  
  67.                    
  68. Compiling this using the /zu flag will result in a 'pointer truncated' 
  69. warning, because it can't pass the 48 bit address of 'retval' using a near 32 
  70. bit pointer.
  71.  
  72. If this kind of code isn't called from a interrupt it'll work anyway, but if 
  73. you want to get rid of those annoying warnings you'll have to force the 
  74. 'retval' variable into the data segment by making it 'static':
  75.  
  76.  
  77.         void foo(void)
  78.         {
  79.            static int retval;
  80.            
  81.            DoCalculation(&retval); 
  82.         }                          
  83.                               
  84.         // This will compile nicely without any warnings.
  85.                         
  86.  
  87. Ofcourse you could also move the 'retval' and make it a global variable, or
  88. pass a far pointer to DoCalculation (yuck!).
  89.  
  90.  
  91. Summary              
  92. =======
  93.  
  94. Steps to take when compiling a Watcom flat model program which uses custom 
  95. interrupt handlers:
  96.  
  97.  
  98. 1. Compile the program using the /zu switch
  99.  
  100. 2. Remove all 'Pointer Truncated' warnings by forcing the involved variables 
  101.    into the data segment (make it static or global). If you forget to do this 
  102.    for code that's going to be called from the interrupt -> CRASSSSH
  103.    
  104. You might notice that I don't compile the loader library using /zu, that's
  105. because these routines aren't called from an interrupt so it's not neccesary.
  106.  
  107.  
  108.